home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
program
/
xlibp202.zip
/
XBM2.DOC
< prev
next >
Wrap
Text File
|
1994-06-18
|
20KB
|
438 lines
╔═══════════════════════════════════════════════════════════════════════════╗
║ ║
║ XLIB v2.0 - Graphics Library for Borland/Turbo Pascal 7.0 ║
║ ║
║ Tristan Tarrant - tristant@cogs.susx.ac.uk ║
║ ║
╠═══════════════════════════════════════════════════════════════════════════╣
║ ║
║ Credits ║
║ ║
║ Themie Gouthas ║
║ ║
║ Matthew MacKenzie ║
║ ║
║ Tore Bastiansen ║
║ ║
║ Andy Tam ║
║ ║
║ Douglas Webb ║
║ ║
║ John Schlagel ║
║ ║
╠═══════════════════════════════════════════════════════════════════════════╣
║ ║
║ I informally reserve all rights to the code in XLIB ║
║ Rights to contributed code is also assumed to be reserved by ║
║ the original authors. ║
║ ║
╚═══════════════════════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════════════════════╗
║ DISCLAIMER ║
╚═══════════════════════════════════════════════════════════════════════════╝
This library is distributed AS IS. The author/s specifically disclaim any
responsibility for any loss of profit or any incidental, consequential or
other damages.
╔═══════════════════════════════════════════════════════════════════════════╗
║ XBM2 : EXPORTED PROCEDURES AND FUNCTIONS ║
╚═══════════════════════════════════════════════════════════════════════════╝
This unit implements a set of functions to operate on bitmaps. XLIB2 uses
three different kinds of bitmaps :
Planar Bitmaps (PBMs),
Video Bitmaps (VBMs),
Compiled Bitmaps (CBMs).
╔═══════════════════════════════════════════════════════════════════════════╗
║ PBMs : EXPORTED PROCEDURES AND FUNCTIONS ║
╚═══════════════════════════════════════════════════════════════════════════╝
PBMs as used by these functions have the following structure:
byte 0 The bitmap width in bytes (4 pixel groups) range 1..255
byte 1 The bitmap height in rows range 1..255
byte 2..n1 The plane 0 pixels width*height bytes
byte n1..n2 The plane 1 pixels width*height bytes
byte n2..n3 The plane 2 pixels width*height bytes
byte n3..n4 The plane 3 pixels width*height bytes
These functions provide the fastest possible bitmap blts from system ram
to video and further, the single bitmap is applicable to all pixel
alignments. The masked functions do not need separate masks since all non
zero pixels are considered to be masking pixels, hence if a pixel is 0 the
corresponding screen destination pixel is left unchanged.
xputmaskedpbm
-------------
Procedure xputmaskedpbm( X, Y, ScrnOffs : word; var Bitmap);
Mask write a planar bitmap from system ram to video ram. All zero source
bitmap bytes indicate destination byte to be left unchanged.
Source Bitmap structure:
Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
Bitmap data (plane 2)..,Bitmap data (plane 3)..
NOTE: width is in bytes ie lots of 4 pixels
LIMITATIONS: No clipping is supported
Only supports bitmaps with widths which are a multiple of
4 pixels
xputpbm
-------
Procedure xputpbm( X, Y, ScrnOffs : word; var Bitmap );
Write a planar bitmap from system ram to video ram.
Source Bitmap structure:
Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
Bitmap data (plane 2)..,Bitmap data (plane 3)..
NOTE: width is in bytes ie lots of 4 pixels
LIMITATIONS: No clipping is supported
Only supports bitmaps with widths which are a multiple of
4 pixels
xgetpbm
-------
Procedure xgetpbm( X, Y : word; Bw, Bh : byte; ScrnOffs : word;
var Bitmap );
Read a planar bitmap to system ram from video ram.
Source Bitmap structure:
Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
Bitmap data (plane 2)..,Bitmap data (plane 3)..
NOTE: width is in bytes ie lots of 4 pixels
LIMITATIONS: No clipping is supported
Only supports bitmaps with widths which are a multiple of
4 pixels
A similar set of functions have been implemented to operate on planar
bitmaps but incorporating clipping to a user defined
clipping rectangle (which is set by xsetcliprect )
There are three variations of the normal functions in this unit
identified by the three function name extensions: clipx, clipy clipxy.
Because speed is critical in games programming you do not want to be
checking for clipping if not necessary thus for sprites that move only
horizontally you would use the clipx version of the put function,
for sprites that move vertically you would use the clipy version and for
sprites that move both directions you would use the clipxy version.
Keep in mind also that the clipping components of these functions assume
that the clipping rectangle is equal to or larger than the size of the
bitmap ie. if a bitmap is top clipped, it is assumed that the bitmap's
bottom is not also clipped. Similarly with horizontal clipping.
Note: performance in decreasing order is as follows.
clipy,clipx,clipxy with masked puts being slower than unmasked puts
Horizontal clipping is performed to byte boundaries (4 pixels) rather than
pixels. This allows for the fastest implementation of the functions. It is
not such a handicap because for one, your screen width a multiple of 4
pixels wide and for most purposes it is the screen edges that form the
clipping rectangle.
Following is an example of setting a clipping rectangle to the logical
screen edges:
xsetcliprect(0,0,ScrnLogicalByteWidth,ScrnLogicalHeight)
NOTE: the functions now return a value;
1 if clipped image is fully clipped (ie no portion of it
appears on the screen) otherwise it returns 0
xputpbmclipx
------------
xputpbmclipy
------------
xputpbmclipxy
-------------
xputmaskedpbmclipx
------------------
xputmaskedpbmclipy
------------------
xputmaskedpbmclipxy
-------------------
For a detailed description of parameters etc. see equivalent functions
xputpbm, xputmaskedpbm
╔═══════════════════════════════════════════════════════════════════════════╗
║ CBMs : EXPORTED PROCEDURES AND FUNCTIONS ║
╚═══════════════════════════════════════════════════════════════════════════╝
o xcompilebitmap compiles your bitmap into native code which writes
to the VGA screen in an X mode.
o xputcbitmap converts X and Y coordinates into a location on the
screen, sets up the necessary VGA registers, and executes the compiled
bitmap as a subroutine.
o xsizeofcbitmap takes a planar bitmap and returns an integer equal to
the size of the compiled bitmap which the planar bitmap would produce.
It is essentially a lobotomized version of xcompilebitmap, with all
the code generation replaced with a size counter.
xcompilebitmap scans through a source bitmap and generates 8086
instructions to plot every nonzero pixel. It is designed to be used
before the action begins rather than on-the-fly. The compiled bitmap
contains no branches, and no reference to the zero (transparent) pixels.
Where two pixels are exactly four columns apart they are plotted with a
single 16-bit store, and the VGA MAPMASK register will be set at most
four times. As a result your bitmap may run several times faster than a
traditional memory-to-VGA masked blit routine.
There is no way to perform clipping on these bitmaps, or to plot a
pixel of color zero.
xcompilebitmap works with bitmaps in the standard Xlib planar bitmap
format. On a time scale of 60 frames per second, it is actually relatively
slow. Since a compiled bitmap is relocatable you may just want to have it
saved to disk, and not include the source bitmap in your program at all.
The source bitmap format is an array of bytes, a little like this:
eye : array[0..29] of byte =
( 4, 7, { four byte columns across, seven rows tall }
0, 0, 0, 0, 9, 1, 1, 1, 9, 0, 0, 0, 0, 0, 0, 0,
0, 0, 9, 9, 1, 1, 1, 4, 4, 9, 9, 0, 0, 0, 0, 0,
0, 9, 9, 1, 2, 0, 0, 4, 4, 1, 9, 9, 0, 0, 0, 0,
9, 9, 9, 1, 0, 0, 0, 0, 1, 1, 9, 9, 9, 0, 0, 0,
0, 9, 9, 1, 2, 0, 0, 2, 1, 1, 9, 9, 0, 0, 0, 0,
0, 0, 9, 9, 1, 1, 1, 1, 1, 9, 9, 0, 0, 0, 0, 0,
0, 0, 0, 0, 9, 1, 1, 1, 9, 0, 0, 0, 0, 0, 0, 0 );
This is actually a linear bitmap, which is the wrong format for
compilation, but is easier on human eyes.
To compile this image for a mode 360 pixels (90 byte columns) across:
var
planareye : array[0..29] of byte;
CompiledEye : pointer;
xbmtopbm( eye, planareye);
getmem( CompiledEye, xsizeofcbitmap(planareye));
xcompilebitmap(90, planareye, CompiledEye^);
Notice that both buffers must exist beforehand. Since xcompilebitmap
returns the size of the compiled code, in bytes, you can reallocate the
bitmap immediately to the right size if using xsizeofxbitmap seems
inconvenient (reallocation may even be faster, though using the function is
cleaner). The pointers are 32-bit because compiled bitmaps take so much
space: they are at one end of the speed-versus-memory spectrum. A good
rule of thumb is to allocate (3.5 x buffer-height x buffer-width) + 25
bytes (rounding up ;-), then pare your bitmap down when you find out how
much space you've actually used.
Since the compiled bitmap has to fit within one segment of memory, it
cannot contain more than about 19,000 pixels. This will not be a
limitation for most sane programmers. If you are not a sane programmer try
splitting your huge, unwieldy image up into smaller parts -- you can use
the same gigantic bitmap if you divide it into horizontal slices for
compilation. For that matter, dividing the source up that way will let
you use a source bitmap large than 64K, which is an even sicker idea...
Back to business. A bitmap is compiled for only one width of screen.
If you are using a logical screen larger than your physical screen, call
the bitmap compiler with the logical width -- the important thing is the
number of bytes per line. Notice that you do not have to be in a graphics
mode to use this routine. This allows you to develop and compile bitmaps
separately, with whatever utility programs you might cook up.
The final function is xputcbitmap. To plot our eye at (99,4), on
the page which starts at location 0:
xputcbitmap(99, 4, 0, CompiledEye);
This function depends on the global variable ScrnLogicalByteWidth which
should be the same number as the column parameter you used to compile your
bitmap.
The XBM2 unit supports memory-to-VGA blits only. XBM2 also includes
non-masking routines which can quickly save and restore the background
screen behind your bitmap, using fast string operations.
xcompilepbm
-----------
xsizeofcpbm
-----------
These two procs are similar to the previous two, though they work on PBMs.
There is also a set of procs that produces 32bit bitmaps. These are slightly
larger and slower (why?), but they are there for compatibility reasons.
╔═══════════════════════════════════════════════════════════════════════════╗
║ VBMs : EXPORTED PROCEDURES AND FUNCTIONS ║
╚═══════════════════════════════════════════════════════════════════════════╝
Yet another type of bitmap to complement planar and compiled bitmaps are
Video Bitmaps, VRAM based bitmaps. If a 4 cylinder car is analagous to planar
bitmaps, that is thrifty on memory consumption but low performance and and a
V8 is analagous to Compiled bitmaps, memory guzzlers that really fly, then
VRAM based bitmaps are the 6 cylinder modest performers with acceptable memory
consumption. They are faster, though, only on VLB/PCI video boards.
To summarise their selling points, VBM's are moderately fast with fair memory
consumption, and unlike compiled bitmaps, can be clipped. The disadvantages
are that they are limited by the amount of free video ram and have a complex
structure.
The VRAM bitmap format is rather complex consisting of components stored in
video ram and components in system ram working together. This complexity
necessitates the existence of a creation function xmakevbm which takes
an input linear bitmap and generates the equivalent VBM (VRAM Bit Map).
VBM structure:
word 0 Size Total size of this VBM structure in bytes
word 1 ImageWidth Width in bytes of the image (for all alignments)
word 2 ImageHeight Height in scan lines of the image
word 3 Alignment 0 ImagePtr Offset in VidRAM of this aligned image
+--word 4 MaskPtr Offset (within this structure's DS) of
| . alignment masks
| .
| .
| word 9 Alignment 3 ImagePtr Offset in VidRAM of this aligned image
+|--word 10 MaskPtr Offset (within this structure's DS) of
|| alignment masks
||
|+->byte 21 (word 11) -------+-- Image masks for alignment 0
| . |
| . |
| byte 21 + ImageWidth*ImageHeight -----+
|
| .
| . (similaly for alignments 1 - 2 )
| .
|
+-->byte 21 + 3*ImageWidth*ImageHeight + 1-+-- Image masks for alignment 3
. |
. |
byte 21 + 4*(ImageWidth*ImageHeight) --+
.
.
<< Similarly for alignments 2 and 3 >>
.
.
byte 21 + 4*(ImageWidth*ImageHeight)
-------------
(And dont forget the corresponding data in video ram)
You can see for yourself the complexity of this bitmap format. The image
is stored in video ram in its 4 different alignments with pointers to these
alignments in the VBM. Similarly there are 4 alignments of the corresponding
masks within the VBM itself (towards the end). The mask bytes contain the
plane settings for the corresponding video bytes so that one memory move can
move up to 4 pixels at a time (depending on the mask settings) using the
VGA's latches, theoretically giving you a 4x speed improvement over
conventional blits like the ones implemented in XPBITMAP. In actual fact
its anywhere between 2 and 3 due to incurred overheads.
These bitmaps are more difficult to store in files than PBM'S and CBM's but
still posible with a bit of work, so do not dismiss these as too difficult
to use. Consider all the bitmap formats carefully before deciding on which
to use. There may even be situations that a careful application of all three
types would be most effective ie. compiled bitmaps for Background tiles and
the main game character (which never need clipping), VRAM based bitmaps for
the most frequently occuring (oponent, alien etc) characters which get
clipped as they come into and leave your current location and planar bitmaps
for smaller or less frequently encountered characters.
xmakevbm
--------
function xmakevbm( var lbm; var VramStart : word) : pointer;
Create the VBM from the given linear bitmap and place the image alignments
in video ram starting at the offset in the variable pointed to by
VramStart. VramStart is then updated to point to the next free VRAM byte
(just after the last byte of the image alignments). Usually you will point
VramStart to NonVisualOffs.
lbm Pointer to the input linear bitmap
VramStart Pointer to variable containing Offset of first free VRAM byte
xputmaskedvbm
-------------
function xputmaskedvbm( X, Y, ScrnOffs : word; var VBitmap) : integer;
Draw a VRAM based bitmap at (X,Y) relative to the screen with starting
offset ScrnOffs.
Returns 1 if clipped image is fully clipped (ie no portion of it
appears on the screen) otherwise it returns 0
xputmaskedvbmclipx
------------------
xputmaskedvbmclipy
------------------
xputmaskedvbmclipxy
-------------------
Clipping versions of xputmaskedvbm.
╔═══════════════════════════════════════════════════════════════════════════╗
║ XBM2 : EXTRA PROCEDURES AND FUNCTIONS ║
╚═══════════════════════════════════════════════════════════════════════════╝
LINEAR BITMAPS
Linear bitmaps have the following structure:
byte 0 The bitmap width in pixels range 1..255
byte 1 The bitmap height in rows range 1..255
byte 2..n The width*height bytes of the bitmap
xpbmtobm
--------
function xpbmtobm( var sourcepbm, destbm ) : integer;
This function converts a bitmap in the planar format to the linear format
as used by xcompilebitmap.
WARNING: the source and destination bitmaps must be pre - allocated
NOTE: This function can only convert planar bitmaps that are suitable.
If the source planar bitmap's width (per plane) is >= 256/4
it cannot be converted. In this situation an error code
BMWIDTHERROR. On successful conversion 0 is returned.
xbmtopbm
--------
function xbmtopbm( var sourcepbm, destbm ) : integer;
This function converts a bitmap in the linear format as used by
xcompilebitmap to the planar formap.
WARNING: the source and destination bitmaps must be pre - allocated
NOTE: This function can only convert linear bitmaps that are suitable.
If the source linear bitmap's width is not a multiple of 4
it cannot be converted. In this situation an error code
BMWIDTHERROR. On successful conversion 0 is returned.
xscale
------
Procedure XScale( DestX, DestY, DestWidth, DestHeight, ScrnOffs : word;
var Bitmap );
xmaskedscale
------------
Procedure XMaskedScale( DestX, DestY, DestWidth, DestHeight, ScrnOffs : word;
var Bitmap );
These two procedures put a linear bitmap in VRAM, scaling it to DestWidth
and DestHeight size, at position DestX,DestY at offset ScrnOffs.
I have tried to write similar functions to work with PBMs, but they are
slower, because of the way PBMs are organised. If you have a PBM you want to
scale, just convert it to an LBM using pbmtobm.